/**
 * 
 */
package wayic.utunes.lyrics;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import org.apache.log4j.Logger;

import wayic.search.GoogleQuery;
import wayic.itunes.api.IITTrack;
import wayic.search.Hit;
import wayic.search.QueryBuilder;
import wayic.search.Result;
import wayic.utils.SearchUtils;

/**
 * @author Pihu
 * 
 */
public class LyricsQuery extends GoogleQuery implements QueryBuilder {
    private static Logger                  LOGGER              = Logger.getLogger(LyricsQuery.class);

    private final static String            DEFAULT_REPLACEMENT = " ";
    private final static String            stopWords[]         = new String[] { "\\(", "\\)", "-", "_", "HQ", "\\+" };
    private final static String            ignoreSites[]       = "rhapsody,lastfm,nutsie,mog,smashits,truveo,nme,youtube,nationmaster,wikipedia,blogspot,scribd"
                                                                       .split(",");

    private static HashMap<String, String> artistIgnores       = new HashMap<String, String>();
    static {
        artistIgnores.put("Krishna Das", "uulyrics,tsrocks");
    }

    private IITTrack                       track;

    public IITTrack getTrack() {
        return track;
    }

    public void setTrack(IITTrack track) {
        this.track = track;
    }

    public LyricsQuery(IITTrack track) {
        this.track = track;
    }

    protected String cleanString(String string) {
        String cleanString = string;
        if (getStopWords() != null) {
            for (String stopWord : getStopWords()) {
                cleanString = cleanString.replaceAll(stopWord, DEFAULT_REPLACEMENT);
            }
        }
        return cleanString;
    }

    /**
     * @see wayic.search.QueryBuilder#getQueryString(java.lang.Object)
     */
    @Override
    public String getQueryString(Object object) {
        if (object == null || !(object instanceof IITTrack)) {
            return null;
        }
        IITTrack track = (IITTrack) object;
        StringBuilder queryBuilder = new StringBuilder();
        
        if (track.artist() != null) {
            queryBuilder.append(cleanString(track.artist()));
            queryBuilder.append(" ");
            queryBuilder.append("+ ");
        }

        if (track.name() != null) {
            queryBuilder.append(cleanString(track.name()));
            queryBuilder.append(" ");
        }

        if (queryBuilder.length() > 0) {
            queryBuilder.append("+ ");
            queryBuilder.append("lyrics");
            return queryBuilder.toString();
        }
        return null;
    }

    public Result search() {
        if (getTrack() == null) {
            return null;
        }
        String searchString = getQueryString(getTrack());
        LOGGER.debug("Searching Google for - " + searchString);
        if (searchString == null) {
            return null;
        }
        Result result = filterHits(super.search(searchString));
        LOGGER.debug("Estimated results - " + result.getEstimatedCount());
        return result;
    }

    /**
     * @see wayic.search.QueryBuilder#getStopWords()
     */
    @Override
    public String[] getStopWords() {
        return stopWords;
    }

    protected Result filterHits(Result result) {
        Set<Hit> hits = result.getHits();
        if (hits.size() > 0) {
            Iterator<Hit> hitIter = hits.iterator();
            while (hitIter.hasNext()) {
                Hit hit = hitIter.next();
                if (irrelevant(hit) || artistIgnores(hit, getTrack())) {
                    hitIter.remove();
                }
            }
        }
        return result;

    }

    private boolean irrelevant(Hit hit) {
        for (String ignore : ignoreSites) {
            String hitSite = SearchUtils.friendlyName(hit.getUrl().getHost());
            if (ignore.equalsIgnoreCase(hitSite)) {
                LOGGER.info("Ignoring bad Google result - " + hit.getUrl());
                return true;
            }
        }
        return false;
    }

    private boolean artistIgnores(Hit hit, IITTrack track) {
        for (String artist : artistIgnores.keySet()) {
            if (artist.equalsIgnoreCase(track.artist())) {
                String ignoreSites = artistIgnores.get(artist);
                for (String ignore : ignoreSites.split(",")) {
                    if (ignore.equalsIgnoreCase(SearchUtils.friendlyName(hit.getUrl().getHost()))) {
                        LOGGER.info("Ignoring unfriendly site for " + artist + " - " + hit.getUrl());
                        return true;
                    }
                }
            }
        }
        return false;
    }

}
